package virtual.utils;

import android.app.AlertDialog;
import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.widget.Toast;

import com.lody.virtual.GmsSupport;
import com.lody.virtual.client.core.InstallStrategy;
import com.lody.virtual.client.core.VirtualCore;
import com.lody.virtual.os.VUserInfo;
import com.lody.virtual.os.VUserManager;
import com.lody.virtual.remote.InstallResult;
import com.lody.virtual.remote.InstalledAppInfo;

import java.io.IOException;
import java.util.List;

import virtual.models.AppData;
import virtual.models.AppInfoLite;
import virtual.models.MultiplePackageAppData;
import virtual.models.PackageAppData;
import virtual.repo.AppRepository;
import virtual.repo.PackageAppDataStorage;

/**
 * @author gaoxin 2019-07-13 17:39
 * @version V1.0.0
 * @name AppvirtualUtils
 * @mail godfeer@aliyun.com
 * @description virtualAPP 工具类
 */
public class AppVirtualUtils {

//    /***
//     * 启动游戏
//     */
//    private void initLaunch(Context context, String packageName) {
//
//        Intent intent = VirtualCore.get().getLaunchIntent(packageName, Content.USER_PERMISSIONS);
//        intent.putExtra("gameID", String.valueOf(getModulesBean().getModuleType()));
//        intent.putExtra("className", getModulesBean().getModuleName());
//        intent.putExtra("classId", getModulesBean().getModuleId());
//        intent.putExtra("userID", AppUtils.getImei(context));
//        VActivityManager.get().startActivity(intent, Content.USER_PERMISSIONS);
//    }
    /****
     * 批量安装
     * @param list 包名列表
     * @param userId 默认用户ID
     */
    private static void installPackages(List<String> list, int userId) {
        VirtualCore core = VirtualCore.get();
        for (String packageName : list) {
            if (core.isAppInstalledAsUser(userId, packageName)) {
                continue;
            }
            ApplicationInfo info = null;
            try {
                info = VirtualCore.get().getUnHookPackageManager().getApplicationInfo(packageName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                // Ignore
            }
            if (info == null || info.sourceDir == null) {
                continue;
            }
            if (userId == 0) {
                core.installPackage(info.sourceDir, InstallStrategy.DEPEND_SYSTEM_IF_EXIST);
            } else {
                core.installPackageAsUser(userId, packageName);
            }
        }
    }

    /***
     * 安装Google服务框架 如果某些软件使用的google的服务 需要使用这个安装
     * @param content
     */
    public void askInstallGms(Context content) {
        new AlertDialog.Builder(content)
                .setTitle("Hi")
                .setMessage("We found that your device has been installed the Google service, whether you need to install them?")
                .setPositiveButton(android.R.string.ok, (dialog, which) -> {
                    VUiKit.defer().when(() -> {
                        GmsSupport.installGApps(0);
                    }).done((res) -> {
                        Toast.makeText(content, "install success~", Toast.LENGTH_LONG).show();
                    });
                })
                .setNegativeButton(android.R.string.cancel, (dialog, which) ->
                        Toast.makeText(content, "You can also find it in the Settings~", Toast.LENGTH_LONG).show())
                .setCancelable(false)
                .show();
    }

    private AppRepository mRepo;
    private OnAppStatusListener onAppStatusListener;

    public AppVirtualUtils(Context context) {
        mRepo = new AppRepository(context);
    }

    /***
     * 批量安装APP
     * @param info
     */
    public void addApp(AppInfoLite info) {
        class AddResult {
            private PackageAppData appData;
            private int userId;
            private boolean justEnableHidden;
        }
        AddResult addResult = new AddResult();
        VUiKit.defer().when(() -> {
            InstalledAppInfo installedAppInfo = VirtualCore.get().getInstalledAppInfo(info.packageName, 0);
            addResult.justEnableHidden = installedAppInfo != null;
            if (addResult.justEnableHidden) {
                int[] userIds = installedAppInfo.getInstalledUsers();
                int nextUserId = userIds.length;
                /*
                  Input : userIds = {0, 1, 3}
                  Output: nextUserId = 2
                 */
                for (int i = 0; i < userIds.length; i++) {
                    if (userIds[i] != i) {
                        nextUserId = i;
                        break;
                    }
                }
                addResult.userId = nextUserId;

                if (VUserManager.get().getUserInfo(nextUserId) == null) {
                    // user not exist, create it automatically.
                    String nextUserName = "Space " + (nextUserId + 1);
                    VUserInfo newUserInfo = VUserManager.get().createUser(nextUserName, VUserInfo.FLAG_ADMIN);
                    if (newUserInfo == null) {
                        throw new IllegalStateException();
                    }
                }
                boolean success = VirtualCore.get().installPackageAsUser(nextUserId, info.packageName);
                if (!success) {
                    throw new IllegalStateException();
                }
            } else {
                InstallResult res = mRepo.addVirtualApp(info);
                if (!res.isSuccess) {
                    throw new IllegalStateException();
                }
            }
        }).then((res) -> {
            addResult.appData = PackageAppDataStorage.get().acquire(info.packageName);
        }).done(res -> {
            boolean multipleVersion = addResult.justEnableHidden && addResult.userId != 0;
            if (!multipleVersion) {
                PackageAppData data = addResult.appData;
                data.isLoading = true;
                onAppStatusListener.setInstallData(data);
                handleOptApp(data, info.packageName, true);
            } else {
                MultiplePackageAppData data = new MultiplePackageAppData(addResult.appData, addResult.userId);
                data.isLoading = true;
                onAppStatusListener.setInstallData(data);
                handleOptApp(data, info.packageName, false);
            }
        });
    }

    /***
     * 安装状态刷新
     * @param data
     * @param packageName
     * @param needOpt
     */
    private void handleOptApp(AppData data, String packageName, boolean needOpt) {
        VUiKit.defer().when(() -> {
            long time = System.currentTimeMillis();
            if (needOpt) {
                try {

                    VirtualCore.get().preOpt(packageName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            time = System.currentTimeMillis() - time;
            if (time < 1500L) {
                try {
                    Thread.sleep(1500L - time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).done((res) -> {
            if (data instanceof PackageAppData) {
                ((PackageAppData) data).isLoading = false;
                ((PackageAppData) data).isFirstOpen = true;
            } else if (data instanceof MultiplePackageAppData) {
                ((MultiplePackageAppData) data).isLoading = false;
                ((MultiplePackageAppData) data).isFirstOpen = true;
            }
            if (onAppStatusListener!= null){
                onAppStatusListener.setRefreshData(data);
            }
        });
    }

    /***
     * 删除APP
     * @param data d
     */
    public void deleteApp(AppData data) {
        try {
            if (onAppStatusListener!= null){
                onAppStatusListener.setRemoveAppRefreshData(data);
            }
            if (data instanceof PackageAppData) {
                mRepo.removeVirtualApp(((PackageAppData) data).packageName, 0);
            } else {
                MultiplePackageAppData appData = (MultiplePackageAppData) data;
                mRepo.removeVirtualApp(appData.appInfo.packageName, appData.userId);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public void setOnAppStatusListener(OnAppStatusListener onAppStatusListener) {
        this.onAppStatusListener = onAppStatusListener;
    }

    /**
     * @author gaoxin 2019-07-13 18:07
     * @version V1.0.0
     * @name AppVirtualUtils
     * @mail godfeer@aliyun.com
     * @description 安装卸载状态监听
     */
    public interface OnAppStatusListener {
        void setInstallData(AppData installAppData);
        void setRefreshData(AppData refreshData);
        void setRemoveAppRefreshData(AppData removeAppData);
    }
}
